﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using BookClub.Web.DataModel;

namespace BookClub.Web.Services {

    // Represents the authentication service for the application. This works against the Members
    // table in the database, rather than the default ASP.NET membership system, since we
    // have our own model for tracking users in the system intrinsically as part of the application's
    // data model.
    [EnableClientAccess]
    public class AuthenticationService : FormsAuthenticationService<User> {

        public AuthenticationService()
            : base(/* enableRoles */ true) {
        }

        protected override User ValidateCredentials(string name, string password, string customData) {
            // NOTE: This is demo-only (to induce latency for ensuring login progress is visible)
            System.Threading.Thread.Sleep(2000);

            User user = null;
            using (BookClubEntities bookClubObjectContext = new BookClubEntities()) {
                Member member = bookClubObjectContext.Members.Where(m => m.MemberAlias == name).FirstOrDefault();

                if ((member != null) && Authentication.ValidatePassword(password, member.PasswordHash)) {
                    user = new User() {
                        Name = name,
                        Roles = member.IsAdmin ? new string[] { "Admin" } : null,
                        MemberID = member.MemberID,
                        DisplayName = member.MemberName
                    };

                    if (member.LoginDate != DateTime.UtcNow.Date) {
                        member.LoginDate = DateTime.UtcNow.Date;
                        bookClubObjectContext.SaveChanges();
                    }
                }
            }

            return user;
        }
    }
}
